#pragma once
#include "../CGIContext.h"
#include "Runtime/CGI/CGIResource.h"
#include "Runtime/CGI/GraphicsPipelineStateInitializer.h"

namespace Alice
{
    class CGIVulkan;
    class VulkanDevice;
    class VulkanQueue;
    class VulkanRenderPass;
    class VulkanFramebuffer;
    class CGIVulkanCommandBufferManager;
    class VulkanPendingGraphicsState;
    class VulkanCommandListContext : public ICGICommandContext
    {
    public:
        CGIVulkan* mRHI;
        VulkanCommandListContext* mImmediate;
        VulkanDevice* mDevice;
        VulkanQueue* mQueue;
        CGIVulkanCommandBufferManager* mCommandBufferManager;
        VulkanRenderPass* mCurrentRenderPass = nullptr;
        VulkanFramebuffer* mCurrentFramebuffer = nullptr;
        VulkanPendingGraphicsState*mPendingGraphicsState;
        VulkanCommandListContext(CGIVulkan* InRHI, VulkanDevice* InDevice, VulkanQueue* InQueue, VulkanCommandListContext* InImmediate);
        inline CGIVulkanCommandBufferManager* GetCommandBufferManager() const
        {
            return mCommandBufferManager;
        }
        inline VulkanQueue* GetQueue() const
        {
            return mQueue;
        }
        virtual void RHIBeginDrawingViewport(CGIViewport* inViewport, CGITexture* inCGITexture) override;
        virtual void RHIEndDrawingViewport(CGIViewport* Viewport, bool bPresent, bool bLockToVsync) override;
        virtual void RHIBeginRenderPass(const CGIRenderPassInfo* InInfo, const TCHAR* InName) override;
        virtual void RHIEndRenderPass() override;
        virtual void RHISetGraphicsPipelineState(CGIGraphicsPipelineState* GraphicsState, uint32 StencilRef, bool bApplyAdditionalState) override;
        virtual void RHISetStreamSource(uint32 StreamIndex, CGIBuffer* VertexBuffer, uint32 Offset) override;
        virtual void RHIDrawPrimitive(uint32 BaseVertexIndex, uint32 NumPrimitives, uint32 NumInstances) override;
        static inline VulkanCommandListContext& GetVulkanContext(ICGICommandContext& CmdContext)
        {
            return static_cast<VulkanCommandListContext&>(CmdContext.GetLowestLevelContext());
        }
        VulkanRenderPass* PrepareRenderPassForPSOCreation(const FGraphicsPipelineStateInitializer& Initializer);
    };
    class CGIVulkanCommandListContextImmediate : public VulkanCommandListContext
    {
    public:
        CGIVulkanCommandListContextImmediate(CGIVulkan* InRHI, VulkanDevice* InDevice, VulkanQueue* InQueue);
    };
}
